#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<unistd.h>

#define Strnumber 64
#define SIZE 1024
#define Group " "


char* slistr[Strnumber];
char nearpath[SIZE];
char path[SIZE];

int redir_type = NoneRedir;
char *filename = NULL;
int flagnear = 0;
int lastcode = 0;


char* Username()
{
  return getenv("USER");
}

char* Hostname()
{
  return getenv("HOSTNAME");
}

char* Pwd()
{
  return getenv("PWD");
}

void Get_Hint()
{
  if(strcmp(Username(),"root")==0)
  {
   printf("[root@%s %s]#",Hostname(),Pwd());
  }
  else
  {
   printf("[%s@%s %s]$",Username(),Hostname(),Pwd());
  }
}

void Get_String(char* arr)
{
  //1.获取一行字符串
  scanf("%[^\n]s",arr);
  
  //2.打印获取到的字符串：
  //printf("%s\n",arr);  
  
}

void Slicing(char* arr)
{
  int i=0;
  slistr[i++] = strtok(arr,Group);
  while(slistr[i++] = strtok(NULL,Group));
  if(strcmp(slistr[0],"ls")==0)
  {
    slistr[i-1] = (char*)("--color");
    slistr[i] = NULL;
  }
} 


void cmd(int * flag)
{
    //1.考虑对内建命令进行处理：
    if(strcmp(slistr[0],"cd")==0)
    {
      if(strcmp(slistr[1],"~")==0)
      {
        strcpy(nearpath,getenv("PWD"));
        chdir(getenv("OLDPWD"));
      }
      else if (strcmp(slistr[1],"-")==0)
      {
        if(flagnear == 0)
        {
          strcpy(nearpath,getenv("PWD"));
          chdir(nearpath);
          flagnear  = 1;
          return;
        }
        else
        {
          char* tmp = getenv("PWD");
          chdir(nearpath);
          strcpy(nearpath,tmp);
        }
      }
      else if (strcmp(slistr[1],"..")==0 || strcmp(slistr[1],"../")==0)
      {
        strcpy(nearpath,getenv("PWD"));
        chdir("..");

      }
      else
      {
        strcpy(nearpath,getenv("PWD"));
        chdir(slistr[1]);
      }
      
      //更新环境变量
      char temp[1024];
      getcwd(temp,1024);
      snprintf(path,SIZE,"PWD=%s",temp);
      putenv(path);
      *flag = 1;
      return;
    }
}

void Export(int * flag)
{
  if(strcmp(slistr[0],"export")==0)
  {
    char str[2048] = {0};
    strcpy(str,slistr[1]);
    int pos = 0;
    while(str[pos++] != '=');
    str[pos-1] = '\0';

    setenv(str,str+pos,0);
    *flag = 1;
  }
  return;
}

void Echo(int* flag)
{
  if(strcmp(slistr[0],"echo")==0)
  {
    if(slistr[1] == NULL)
      printf("\n");
    else if (slistr[1][0] == '$')
    {
      if(slistr[1][1] == '?')
        printf("%d\n",lastcode);
      else
        printf("%s\n",getenv(slistr[1]+1));
    }
    else 
      printf("%s\n",slistr[1]);

    *flag = 1;
  }
}



void execute()
{
    int flag = 0;
    //1.cd 判断
    if(flag == 0)
      cmd(&flag); 
    //2.export判断
    if(flag == 0)
      Export(&flag);
    //3.echo判断：
    if(flag == 0)
      Echo(&flag);
    //4.创建子进程处理普通命令
    if(flag == 0)
    {

      int id = fork();
      if(id == 0)
      {
        execvp(slistr[0],slistr);
        exit(1);
      }
      int status = 0;
      pid_t rid = waitpid(id, &status, 0);
      if(rid == id) lastcode = WEXITSTATUS(status); 
    }
}
heckRedir(char in[])
{
    // ls -a -l
    // ls -a -l > log.txt
    // ls -a -l >> log.txt
    // cat < log.txt
    redir_type = NoneRedir;
    filename = NULL;
    int pos = strlen(in) - 1;
    while( pos >= 0 )
    {
        if(in[pos] == '>')
        {
            if(in[pos-1] == '>')
            {
                redir_type = AppendRedir;
                in[pos-1] = STREND;
                pos++;
                IgnSpace(in, pos);
                filename = in+pos;
                break;
            }
            else
            {
                redir_type = StdoutRedir;
                in[pos++] = STREND;
                IgnSpace(in, pos);
                filename = in+pos;
                //printf("debug: %s, %d\n", filename, redir_type);
                break;
            }
        }
        else if(in[pos] == '<')
        {
            redir_type = StdinRedir;
            in[pos++] = STREND;
            IgnSpace(in, pos);
            filename = in+pos;
            //printf("debug: %s, %d\n", filename, redir_type);
            break;
        }
        else
        {
            pos--;
        }
    }
}
{
  while(1)
  {
    //1.打印命令行提示符：
    Get_Hint();
    //2.获取用户输入字符串：
    char arr[Strnumber]={0};
    Get_String(arr);
    //3.字符串切割：
    Slicing(arr);
    //4.子进程执行命令：
    execute();
    getchar();
  }
  return 0;
}
